package com.jing.product.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.jing.common.core.utils.StringUtils;
import com.jing.common.core.utils.bean.BeanUtils;
import com.jing.product.domain.dto.*;
import com.jing.product.domain.enums.PriceType;
import com.jing.product.domain.po.*;
import com.jing.product.domain.vo.ProductCategoryVO;
import com.jing.product.domain.vo.ProductVO;
import com.jing.product.mapper.HuixianMapper;
import com.jing.product.mapper.ProductMapper;
import com.jing.product.service.ProductService;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.CompletableFuture;

/**
 * @Author：HaoYunde
 * @Package：com.jing.product.service.impl
 * @Project：Jing
 * @name：ProductServiceImpl
 * @Date：2024/5/23 21:06
 */
@Service
public class ProductServiceImpl implements ProductService {
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private HuixianMapper huixianMapper;

    private static final Logger log = LoggerFactory.getLogger(ProductServiceImpl.class);


    /**
     * 保存商品信息
     * @param productDTO
     */
    @SneakyThrows
    @Override
    public void addProduct(ProductDTO productDTO) {
        //参数校验
        checkParam(productDTO);
        //保存商品基本信息
        saveProduct(productDTO);

        CompletableFuture<Integer> cf1=CompletableFuture.supplyAsync(()->{
           //保存商品优惠信息
           savePromotion(productDTO);
           return null;
        });
        CompletableFuture<Integer> cf2=CompletableFuture.supplyAsync(()->{
           //保存商品sku属性信息
           saveSkuInfo(productDTO);
           return null;
        });
        CompletableFuture<Integer> cf3=CompletableFuture.supplyAsync(()->{
           //保存商品相册信息
           savePicsInfo(productDTO);
           return null;
        });
        CompletableFuture<Integer> cf4=CompletableFuture.supplyAsync(()->{
           //保存商品参数
           saveParamsInfo(productDTO);
           return null;
        });
        cf1.get();
        cf2.get();
        cf3.get();
        cf4.get();
    }




    /**
     * 保存商品参数
     * @param productDTO
     */
    private void saveParamsInfo(ProductDTO productDTO) {
        List<ProductAttributeValueDTO> arrtList = productDTO.getArrtList();
        if(arrtList!=null){
            List<ProductAttributeValue> productAttributeValues = new ArrayList<>();
            for (ProductAttributeValueDTO arrt : arrtList) {
                ProductAttributeValue productAttributeValue = new ProductAttributeValue();
                productAttributeValue.setProductId(productDTO.getId());
                productAttributeValue.setProductAttributeId(arrt.getId());
                productAttributeValue.setValue(arrt.getValue());
                productAttributeValues.add(productAttributeValue);
            }
            productMapper.addProductAttributeValue(productAttributeValues);
        }
    }


    /**
     * 保存商品相册信息
     * @param productDTO
     */
    private void savePicsInfo(ProductDTO productDTO) {
        if(productDTO.getImgUrl()!=null){
            List<String> albumPics = productDTO.getImgUrl();
            List<Img> img = new ArrayList<>();
            for (String albumPic : albumPics) {
                Img img1 = new Img();
                img1.setImgUrl(albumPic);
                img1.setObjectId(productDTO.getId());
                img1.setImgType("product");
                img.add(img1);
            }
            productMapper.addImg(img);
        }
    }


    /**
     * 保存商品sku属性信息
     * @param productDTO
     */
    private void saveSkuInfo(ProductDTO productDTO) {
        List<ProductSkuStock> productSkuStocks = new ArrayList<>();
        List<Img> img = new ArrayList<>();
        List<Map<String, Object>> skuList = productDTO.getProductSkuStock();
        ProductSkuStock productSkuStock = new ProductSkuStock();
        if(skuList!=null){
            for (Map<String, Object> stringStringMap : skuList) {
                ProductSkuStockDTO pskuStockDTO =  JSONObject.parseObject(JSONObject.toJSONString(stringStringMap), ProductSkuStockDTO.class);
                pskuStockDTO.setProductId(productDTO.getId());
                pskuStockDTO.setAtts(getAttrsBySku(stringStringMap));
                BeanUtils.copyBeanProp(productSkuStock,pskuStockDTO);
                productSkuStocks.add(productSkuStock);
                //调用mapper添加sku信息
                productMapper.addProductSku(productSkuStocks);
                List<String> images = pskuStockDTO.getPics();
                for (String image : images) {
                    Img img1 = new Img();
                    img1.setImgUrl(image);
                    img1.setObjectId(pskuStockDTO.getId());
                    img1.setImgType("sku");
                    img.add(img1);
                }
            }
            //取出图片的集合
            productMapper.addImg(img);
        }
    }


    /**
     * 单独获取参数和属性
     * @param stringStringMap
     * @return
     */
    private String getAttrsBySku(Map<String, Object> stringStringMap) {
        //或去除所以得key
        Set<Object> keySets = new HashSet<>(stringStringMap.keySet());
        //获取所以得属性值
        ProductSkuStockDTO productSkuStockDTO = new ProductSkuStockDTO();
        List<String> allFileNames = gerAllFileNames(productSkuStockDTO);
        //遍历keysets和属性值进行对比
        ArrayList<Object> toRemove = new ArrayList<>();
        for (Object keySet : keySets) {
            if(allFileNames.contains(keySet)){
                toRemove.add(keySet);
            }
        }
        keySets.removeAll(toRemove);
        keySets.remove("images");
        ArrayList<Object> values = new ArrayList<>();
        for (Object keySet : keySets) {
            values.add(stringStringMap.get(keySet));
        }
        //拼接values转为逗号的字符串
        String attr = StringUtils.join( ",",values);
        return attr;
    }
    public List<String> gerAllFileNames(Object obj){
        ArrayList<String> fileNames = new ArrayList<>();
        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field declaredField : declaredFields) {
            fileNames.add(declaredField.getName());
        }
        return fileNames;
    }



    /**
     * 保存商品优惠信息
     * @param productDTO
     */
    private void savePromotion(ProductDTO productDTO) {
        PriceType enumByCode = PriceType.getEnumByCode(productDTO.getPromotionType());
        productDTO.getPromotionType();

        switch (enumByCode){
            case ORIGINAL_PRICE:
                //无促销
                break;
            case PROMOTION_PRICE:
                //特惠促销
                ProductPromotion productPromotion = productDTO.getProductPromotion();
                //把商品id赋值给要添加的表
                productPromotion.setProductId(productDTO.getId());
                productMapper.addProductPromotion(productPromotion);
                break;
            case MEMBER_PRICE:
                //会员价
                List<ProductMemberPrice> productMemberPriceList = productDTO.getProductMemberPriceList();
                for (ProductMemberPrice productMemberPrice : productMemberPriceList) {
                    //把商品id赋值给要添加的表
                    productMemberPrice.setProductId(productDTO.getId());
                    productMapper.addProductMemberPrice(productMemberPrice);
                }
                break;
            case LADDER_PRICE:
                //阶梯价格
                List<ProductLadder> productLadderList = productDTO.getProductLadderList();
                for (ProductLadder productLadder : productLadderList) {
                    //把商品id赋值给要添加的表
                    productLadder.setProductId(productDTO.getId());
                    productMapper.addProductLadder(productLadder);
                }
                break;
            case FULL_REDUCTION_PRICE:
                //满减价格
                List<ProductFullReduction> productFullReductionList = productDTO.getProductFullReductionList();
                for (ProductFullReduction productFullReduction : productFullReductionList) {
                    //把商品id赋值给要添加的表
                    productFullReduction.setProductId(productDTO.getId());
                    productMapper.addProductFullReduction(productFullReduction);
                }
                break;
            default:
                break;
        }
    }
    /**
     * 保存商品基本信息
     * @param productDTO
     */
    private void saveProduct(ProductDTO productDTO) {
        //构建po
        Product product = new Product();
        BeanUtils.copyBeanProp(product,productDTO);
        int i=   productMapper.saveProductInfo(product);
        if(i<=0){
            throw new RuntimeException("保存商品基本信息失败，请好好检查！！！");
        }
        //拿到主键的id
        productDTO.setId(product.getId());
    }
    /**
     * 参数校验
     * @param productDTO
     */
    private void checkParam(ProductDTO productDTO) {
        String productSn = productDTO.getProductSn();
        if(StringUtils.isNotEmpty(productSn)){
            //查询数据库是否存在
            List<ProductDTO> list= productMapper.findProductByProductSn(productSn);
            if(list.size()>0){
                throw new RuntimeException("商品货号已存在，请重新输入");
            }
        }
    }
    /**
     * 删除商品表
     * @param id
     */
    @Override
    public void delect(Integer id) {
        int flag=productMapper.delect(id);
        if (flag==0){
            throw new RuntimeException("删除失败");
        }else {
            //删除图片表
            productMapper.delectImg(id);
        }
    }
    /**
     * 修改商品表
     * @param product
     */
    @Override
    public void update(ProductDTO product) {
        int flag=productMapper.update(product);
        if (flag==0){
            throw new RuntimeException("删除失败");
        }else {
            //删除图片表
            productMapper.delectImg(product.getId());
            //重新添加图片
            ArrayList<Img> imgs = new ArrayList<>();
            List<String> imgUrl = product.getImgUrl();
            for (String s : imgUrl) {
                Img img = new Img();
                img.setImgUrl(s);
                img.setObjectId(product.getId());
                img.setImgType("prdouct");
                imgs.add(img);
            }
            productMapper.addImg(imgs);
        }
    }


    /**
     * 查询商品列表
     * @param productVO
     * @return
     */
    @Override
    public List<ProductDTO> findProductList(ProductVO productVO) {
        return productMapper.findProductList(productVO);
    }


    /**
     * 修改商品是否上架
     * @param id
     * @param publishStatus
     */
    @Override
    public void updatepublishStatus(Integer id, Integer publishStatus) {
        int flag=productMapper.updatepublishStatus(id,publishStatus);
        if (flag==0){
            throw new RuntimeException("修改商品是否上架失败");
        }
    }
    /**
     * 修改商品是否新品
     * @param id
     * @param newStatus
     */
    @Override
    public void updatenewStatus(Integer id, Integer newStatus) {
        int flag=productMapper.updatenewStatus(id,newStatus);
        if (flag==0){
            throw new RuntimeException("修改商品是否新品失败");
        }
    }
    /**
     * 修改商品是否推荐
     * @param id
     * @param recommandStatus
     */
    @Override
    public void updaterecommandStatus(Integer id, Integer recommandStatus) {
        int flag=productMapper.updaterecommandStatus(id,recommandStatus);
        if (flag==0){
            throw new RuntimeException("修改商品是否推荐失败");
        }
    }

    @Override
    public ProductResultDTO getUpdateInfo(Integer id) {
        return huixianMapper.getUpdateInfo(id);
    }


    /**
     * 递归
     * @return
     */
    @Override
    public ArrayList<ProductCategoryRecursionDTO> recursion(Integer id) {
        List<ProductCategoryRecursionDTO> list=productMapper.list();
        ArrayList<ProductCategoryRecursionDTO> result=getChilren(list,id);
        return result;
    }
    /**
     * 递归子节点
     * @param list
     * @param id
     * @return
     */
    private ArrayList<ProductCategoryRecursionDTO> getChilren(List<ProductCategoryRecursionDTO> list, Integer id) {
        ArrayList<ProductCategoryRecursionDTO> recursionDTOS = new ArrayList<>();
        for (ProductCategoryRecursionDTO productCategoryRecursionDTO : list) {
            if(productCategoryRecursionDTO.getParentId().equals(Long.valueOf(id))){
                ArrayList<ProductCategoryRecursionDTO> children=getChilren(list,Math.toIntExact(productCategoryRecursionDTO.getId()));
                productCategoryRecursionDTO.setChilren(children);
                recursionDTOS.add(productCategoryRecursionDTO);
            }
        }
        return recursionDTOS;
    }
}
